/**
 * WebSocket 工具类
 * 用于处理校园防欺凌系统的实时通信
 */

class CampusWebSocket {
  constructor() {
    this.ws = null
    this.url = ''
    this.reconnectTimer = null
    this.reconnectCount = 0
    this.maxReconnectCount = 5
    this.reconnectInterval = 5000
    this.heartbeatTimer = null
    this.heartbeatInterval = 30000
    this.listeners = new Map()
  }

  /**
   * 连接WebSocket
   * @param {string} clientId 客户端ID
   * @param {string} type 连接类型 dashboard/alarm/device
   */
  connect(clientId, type = 'dashboard') {
    try {
      // 构建WebSocket URL
      const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
      const wsHost = process.env.NODE_ENV === 'production' 
        ? window.location.host 
        : 'localhost:8080'
      
      this.url = `${wsProtocol}//${wsHost}/websocket/campus-alarm/${type}/${clientId}`
      
      // 创建WebSocket连接
      this.ws = new WebSocket(this.url)
      
      // 设置事件监听器
      this.ws.onopen = this.onOpen.bind(this)
      this.ws.onmessage = this.onMessage.bind(this)
      this.ws.onerror = this.onError.bind(this)
      this.ws.onclose = this.onClose.bind(this)
      
      console.log(`[WebSocket] 正在连接: ${this.url}`)
    } catch (error) {
      console.error('[WebSocket] 连接失败:', error)
    }
  }

  /**
   * 连接打开事件
   */
  onOpen(event) {
    console.log('[WebSocket] 连接成功')
    this.reconnectCount = 0
    this.startHeartbeat()
    
    // 触发连接成功回调
    this.emit('open', event)
  }

  /**
   * 接收消息事件
   */
  onMessage(event) {
    try {
      const data = JSON.parse(event.data)
      console.log('[WebSocket] 收到消息:', data)
      
      // 处理心跳回复
      if (data.type === 'pong') {
        return
      }
      
      // 触发消息回调
      this.emit('message', data)
      
      // 根据消息类型触发特定回调
      if (data.type) {
        this.emit(data.type, data)
      }
      
    } catch (error) {
      console.error('[WebSocket] 消息解析失败:', error)
    }
  }

  /**
   * 连接错误事件
   */
  onError(event) {
    console.error('[WebSocket] 连接错误:', event)
    this.emit('error', event)
  }

  /**
   * 连接关闭事件
   */
  onClose(event) {
    console.log('[WebSocket] 连接关闭:', event.code, event.reason)
    this.stopHeartbeat()
    this.emit('close', event)
    
    // 自动重连
    if (this.reconnectCount < this.maxReconnectCount) {
      this.reconnect()
    }
  }

  /**
   * 发送消息
   */
  send(data) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      const message = typeof data === 'string' ? data : JSON.stringify(data)
      this.ws.send(message)
      console.log('[WebSocket] 发送消息:', data)
    } else {
      console.warn('[WebSocket] 连接未就绪，无法发送消息')
    }
  }

  /**
   * 关闭连接
   */
  close() {
    this.stopHeartbeat()
    this.clearReconnectTimer()
    
    if (this.ws) {
      this.ws.close()
      this.ws = null
    }
    
    console.log('[WebSocket] 手动关闭连接')
  }

  /**
   * 重连
   */
  reconnect() {
    if (this.reconnectCount >= this.maxReconnectCount) {
      console.log('[WebSocket] 达到最大重连次数，停止重连')
      return
    }
    
    this.reconnectCount++
    console.log(`[WebSocket] 第${this.reconnectCount}次重连...`)
    
    this.reconnectTimer = setTimeout(() => {
      this.connect()
    }, this.reconnectInterval)
  }

  /**
   * 清除重连定时器
   */
  clearReconnectTimer() {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
      this.reconnectTimer = null
    }
  }

  /**
   * 开始心跳
   */
  startHeartbeat() {
    this.heartbeatTimer = setInterval(() => {
      this.send({ type: 'ping', timestamp: Date.now() })
    }, this.heartbeatInterval)
  }

  /**
   * 停止心跳
   */
  stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer)
      this.heartbeatTimer = null
    }
  }

  /**
   * 添加事件监听器
   */
  on(event, callback) {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, [])
    }
    this.listeners.get(event).push(callback)
  }

  /**
   * 移除事件监听器
   */
  off(event, callback) {
    if (this.listeners.has(event)) {
      const callbacks = this.listeners.get(event)
      const index = callbacks.indexOf(callback)
      if (index > -1) {
        callbacks.splice(index, 1)
      }
    }
  }

  /**
   * 触发事件
   */
  emit(event, data) {
    if (this.listeners.has(event)) {
      this.listeners.get(event).forEach(callback => {
        try {
          callback(data)
        } catch (error) {
          console.error(`[WebSocket] 事件回调执行失败 [${event}]:`, error)
        }
      })
    }
  }

  /**
   * 获取连接状态
   */
  getReadyState() {
    if (!this.ws) return WebSocket.CLOSED
    return this.ws.readyState
  }

  /**
   * 是否已连接
   */
  isConnected() {
    return this.ws && this.ws.readyState === WebSocket.OPEN
  }
}

// 创建全局实例
const campusWebSocket = new CampusWebSocket()

// 导出工具方法
export default {
  /**
   * 连接WebSocket
   */
  connect(clientId, type) {
    campusWebSocket.connect(clientId, type)
  },

  /**
   * 发送消息
   */
  send(data) {
    campusWebSocket.send(data)
  },

  /**
   * 关闭连接
   */
  close() {
    campusWebSocket.close()
  },

  /**
   * 添加事件监听
   */
  on(event, callback) {
    campusWebSocket.on(event, callback)
  },

  /**
   * 移除事件监听
   */
  off(event, callback) {
    campusWebSocket.off(event, callback)
  },

  /**
   * 获取连接状态
   */
  getReadyState() {
    return campusWebSocket.getReadyState()
  },

  /**
   * 是否已连接
   */
  isConnected() {
    return campusWebSocket.isConnected()
  },

  /**
   * WebSocket状态常量
   */
  CONNECTING: WebSocket.CONNECTING,
  OPEN: WebSocket.OPEN,
  CLOSING: WebSocket.CLOSING,
  CLOSED: WebSocket.CLOSED
} 